package cn.akaba.yun.appCls;

import java.util.LinkedList;
import java.util.List;

public class AppSql {
    private String sql;
    private String tableName;
    private List<String> findFieldList;
    private List<String> whereList = new LinkedList<>();
    private List<String> orList = new LinkedList<>();
    private AppDataBase dataBase;

    public AppSql() {
        this.dataBase = AppDataBase.getInstance();
    }

    public AppSql(AppDataBase dataBase) {
        this.dataBase = dataBase;
    }

    public AppSql select() {
        this.findFieldList = new LinkedList<>();
        return this;
    }

    public AppSql select(List<String> list) {
        this.findFieldList = list;
        return this;
    }

    public AppSql from(String tableName) {
        this.tableName = tableName;
        return this;
    }

    public AppSql where(String fieldName, String fieldValue) {
        return this.where(fieldName, fieldValue, "=");
    }

    public AppSql where(String fieldName, String fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + "\"" + fieldValue + "\"";
        return this.where(whereSql);
    }

    public AppSql where(String fieldName, float fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.where(whereSql);
    }

    public AppSql where(String fieldName, double fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.where(whereSql);
    }

    public AppSql where(String fieldName, long fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.where(whereSql);
    }

    public AppSql where(String fieldName, int fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.where(whereSql);
    }

    public AppSql where(String fieldName, float fieldValue) {
        return this.where(fieldName, fieldValue, "=");
    }

    public AppSql where(String fieldName, double fieldValue) {
        return this.where(fieldName, fieldValue, "=");
    }

    public AppSql where(String fieldName, long fieldValue) {
        return this.where(fieldName, fieldValue, "=");
    }

    public AppSql where(String fieldName, int fieldValue) {
        return this.where(fieldName, fieldValue, "=");
    }

    public AppSql where(String whereSql) {
        this.whereList.add(whereSql);
        return this;
    }
    
    public AppSql where(List<String> whereSql) {
        this.whereList.addAll(whereSql);
        return this;
    }

    public AppSql and(String fieldName, String fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql and(String fieldName, String fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + "\"" + fieldValue + "\"";
        return this.and(whereSql);
    }

    public AppSql and(String fieldName, float fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql and(String fieldName, double fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql and(String fieldName, long fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql and(String fieldName, int fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql and(String fieldName, float fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql and(String fieldName, double fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql and(String fieldName, long fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql and(String fieldName, int fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql and(String whereSql) {
        this.whereList.add(whereSql);
        return this;
    }

    public AppSql and(List<String> whereSql) {
        this.whereList.addAll(whereSql);
        return this;
    }


    public AppSql sqlOr(String fieldName, String fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql sqlOr(String fieldName, String fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + "\"" + fieldValue + "\"";
        return this.and(whereSql);
    }

    public AppSql sqlOr(String fieldName, float fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql sqlOr(String fieldName, double fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql sqlOr(String fieldName, long fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql sqlOr(String fieldName, int fieldValue, String relation) {
        String whereSql = "`" + fieldName + "`" + relation + fieldValue;
        return this.and(whereSql);
    }

    public AppSql sqlOr(String fieldName, float fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql sqlOr(String fieldName, double fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql sqlOr(String fieldName, long fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql sqlOr(String fieldName, int fieldValue) {
        return this.and(fieldName, fieldValue, "=");
    }

    public AppSql sqlOr(String whereSql) {
        this.orList.add(whereSql);
        return this;
    }

    public AppSql sqlOr(List<String> whereSql) {
        this.orList.addAll(whereSql);
        return this;
    }

    public String getFindSql() {
        String where = this.getWhereSql();
        String orSql = this.getOrSql();
        String findSql = this.getSelectSql();
        return "SELECT " + findSql + " " + where + (where.equals("") ? "" : " OR ") + orSql;
    }

    public boolean execute(String sql) {
        if (this.dataBase != null) {
            return this.dataBase.executeSql(sql);
        }
        return false;
    }

    protected String getWhereSql() {
        String where = "";
        if (this.whereList != null && !this.whereList.isEmpty()) {
            where = "WHERE " + String.join(" AND ",  this.whereList);
        }
        return where;
    }

    protected String getOrSql() {
        String orSql = "";
        if (this.orList != null && !this.orList.isEmpty()) {
            orSql = String.join(" OR ", this.orList);
        }
        return orSql;
    }

    protected String getSelectSql() {
        String select = "*";
        if (this.findFieldList != null && this.findFieldList.isEmpty()) {
            List<String> list = new LinkedList<>();
            //noinspection RedundantOperationOnEmptyContainer
            for (String field: this.findFieldList) {
                list.add("`" + field + "`");
            }
            select = String.join(", ", list);
        }
        return select;
    }

    public static AppSql getInstance() {
        return new AppSql();
    }
}
